﻿/*
 * sysdaemon.cpp
 *
 *  Created on: 2018年2月14日
 *      Author: Dylan.Gao
 */

#include "sysdaemon.hpp"
#include <dm/os/log/logger.hpp>
#include <dm/string/stringlist.hpp>
#include <dm/timedtrigger.hpp>

#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <cstdio>
#include <dm/os/scopelock.hpp>
#include <dm/os/sys/sys_mgr.hpp>

#include <boost/process.hpp>

using namespace dm::os::sys;

static const char* logModule = "CSysDaemon.app.dm";

CSysDaemon::CSysDaemon(const bool& console,const bool& nd):m_execInterval(1000),m_me(false),m_console(console),m_nd(nd){
	log().debug(THISMODULE "创建对象");

#ifndef WIN32
	boost::process::pid_t pid = 0;
	if( !m_nd )
		pid = fork();
#endif
	m_pid = getpid();

	dm::os::sys::CSysMgr& sysMgr = dm::os::sys::CSysMgr::ins();

	dm::CRunTimeStamp rtsNow = dm::CRunTimeStamp::cur();
	// todo
//	if( !sysMgr.update(m_pid,,rtsNow) ){
//
//	}
/*
	if( m_info ){
		dm::CTimeStamp n = dm::CTimeStamp::cur();

		boost::process::pid_t pid = m_info->pid;
		dm::os::CScopeLock lock( m_info->lock);

		boost::process::child p(pid);

		if( p.running() ){
			std::cout <<"守护进程已经运行"<<std::endl;
			exit(EXIT_FAILURE);
		}else{




			if( pid==-1 ){
				log().error(THISMODULE "创建进程失败");
				exit(EXIT_FAILURE);
			}else if( pid==0 ){
				dm::os::CLogger::ins().resetPid();
				m_info->pid = getpid();
#ifndef WIN32
				setsid();
				if( !m_console ){
					chdir("/");
					int fd = open("/dev/null",O_RDWR,0);
					if( fd<0 ){
						log().warnning(THISMODULE "打开文件/dev/null失败");
					}else{
						dup2(fd,STDIN_FILENO);
						dup2(fd,STDOUT_FILENO);
						dup2(fd,STDERR_FILENO);
					}
				}
#endif
				log().debug(THISMODULE "创建守护进程成功");

				m_info->sysState = TsRunning;
				m_info->startTs.copy(n);
				m_info->refreshTs.copy(n);

				for( int i=0;i<m_info->taskCount;++i ){
					m_taskInfos[i].init();
					m_taskInfos[i].nextExecTs.copy(n);
				}

				m_me = true;
			}else{
				log().debug(THISMODULE "父进程退出");
				exit(EXIT_SUCCESS);
			}
		}

	}else{
		log().error(THISMODULE "系统信息未正确初始化");
		exit(EXIT_FAILURE);
	}
	*/
}

CSysDaemon::~CSysDaemon(){
	if( m_me ){
		log().info(THISMODULE "平台停机");
//		sysStop();
	}

	log().debug(THISMODULE "当前进程退出");
}

bool CSysDaemon::runOnce(){
//	m_children.wait_for(std::chrono::microseconds(10));

	// 更新设备信息
//	if( m_dev ){
//		const dm::scada::CDeviceMgr& devMgr = dm::scada::CDeviceMgr::ins();
//		dm::CTimeStamp n = dm::CTimeStamp::cur();
//		dm::CRunTimeStamp rn = dm::CRunTimeStamp::cur();
//		for( int i=0;i<devMgr.size();++i ){
//			if( m_dev->getIndex()==i )
//				continue;
//			m_dev->updateStatus(i*Status_Max+Status_Online,devMgr.state(i)->isAlive(rn)?2:1,dm::scada::BySys,n);
//			m_dev->updateDiscrete(i*Discrete_Max+Discrete_State,devMgr.state(i)->getLastState(),dm::scada::BySys,n);
//			m_dev->updateCumulant(i*Cumulant_Max+Cumulant_RxCnt,devMgr.state(i)->getRxCnt().getCount(),dm::scada::BySys,n);
//			m_dev->updateCumulant(i*Cumulant_Max+Cumulant_TxCnt,devMgr.state(i)->getTxCnt().getCount(),dm::scada::BySys,n);
//			m_dev->updateCumulant(i*Cumulant_Max+Cumulant_StartRx,devMgr.state(i)->getRxStart().toTimeStamp(rn,n).seconds(),dm::scada::BySys,n);
//			m_dev->updateCumulant(i*Cumulant_Max+Cumulant_StartTx,devMgr.state(i)->getTxStart().toTimeStamp(rn,n).seconds(),dm::scada::BySys,n);
//			m_dev->updateCumulant(i*Cumulant_Max+Cumulant_LastRx,devMgr.state(i)->getLastRx().toTimeStamp(rn,n).seconds(),dm::scada::BySys,n);
//			m_dev->updateCumulant(i*Cumulant_Max+Cumulant_LastTx,devMgr.state(i)->getLastTx().toTimeStamp(rn,n).seconds(),dm::scada::BySys,n);
//		}
//	}

	// 启动新进程
//	if( m_info->sysState==TsRunning ){
//		dm::os::CScopeLock lock(m_info->lock);
//
//		dm::CTimeStamp n = dm::CTimeStamp::cur();
//
//		for( int i=0;i<taskCount();++i ){
//			STaskInfo& task = m_taskInfos[i];
//			task.lastExamTs.copy(n);
//
//			if( task.disable ){
//				continue;
//			}
//
//			if( task.delaySecs>0 ){
//				if( !m_info->startTs.isTimeout_sec(task.delaySecs,n) )
//					continue;
//			}
//
//			if( task.startMode<0 || task.startMode>=STaskInfo::SmUnknow || task.startMode==STaskInfo::SmDeny || task.startMode==STaskInfo::SmManual ){
//				log().warnning(THISMODULE "%d] 未知启动方式%d",i,task.startMode);
//				continue;
//			}
//
//			// 确保任务没有在运行
//			if( task.ifExist() )
//				continue;
//
//			if( task.startMode==STaskInfo::SmSingle ){
//				if( task.taskState==TsInited ){
//					task.taskState = TsRunning;	// 防止有些非平台程序，多次执行
//					task.nextExecTs.copy(n);
//					log().info(THISMODULE "任务%d 单次执行",i);
//					exec((dm::os::sys::STaskInfo&)task);
//				}
//				// 已经执行过了，就不再执行
//			}else{
//				if( task.startMode==STaskInfo::SmDaemon ){
//					task.nextExecTs.copy(n);
//					log().info(THISMODULE "任务%d 守护执行",i);
//					exec((dm::os::sys::STaskInfo&)task);
//				}else{
//					if( task.nextExecTs<=n ){
//						task.nextExecTs.copy(n);
//						log().debug(THISMODULE "任务%d 定时执行",i);
//						exec((dm::os::sys::STaskInfo&)task);
//
//						dm::CTimedTrigger trigger;
//						switch( task.startMode ){
//						case STaskInfo::SmSecondly:
//							trigger.setTriggerType(dm::CTimedTrigger::TtSecondly);
//							break;
//
//						case STaskInfo::SmMinutely:
//							trigger.setTriggerType(dm::CTimedTrigger::TtMinutely);
//							break;
//
//						case STaskInfo::SmHourly:
//							trigger.setTriggerType(dm::CTimedTrigger::TtHourly);
//							break;
//
//						case STaskInfo::SmDaily:
//							trigger.setTriggerType(dm::CTimedTrigger::TtDaily);
//							break;
//
//						case STaskInfo::SmMonthly:
//							trigger.setTriggerType(dm::CTimedTrigger::TtMonthly);
//							break;
//
//						case STaskInfo::SmYearly:
//							trigger.setTriggerType(dm::CTimedTrigger::TtYearly);
//							break;
//
//						case STaskInfo::SmMondays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtMondays);
//							break;
//
//						case STaskInfo::SmTuesdays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtTuesdays);
//							break;
//
//						case STaskInfo::SmWednesdays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtWednesdays);
//							break;
//
//						case STaskInfo::SmThursdays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtThursdays);
//							break;
//
//						case STaskInfo::SmFridays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtFridays);
//							break;
//
//						case STaskInfo::SmSaturdays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtSaturdays);
//							break;
//
//						case STaskInfo::SmSundays:
//							trigger.setTriggerType(dm::CTimedTrigger::TtSundays);
//							break;
//
//						default:
//							log().warnning(THISMODULE "任务%d的启动方式不正确%d",i,task.startMode);
//							continue;
//						}
//
//						trigger.setStartTime( (dm::CDateTime)(task.time));
//						trigger.prepairNext(n);
//						task.nextExecTs.copy(trigger.getNextTime());
//					}
//				}
//			}
//		}
//
//		return true;
//	}else{
//		log().info(THISMODULE "平台停机");
//		return false;
//	}
	return false;
}

bool CSysDaemon::exec( STaskInfo& task ){
	if( task.program.len()<=0 ){
		log().error(THISMODULE "任务命令为空");
		return false;
	}

//	if (task.paras.len() > 0) {
//		boost::process::child(task.program.c_str(), task.paras.c_str(), boost::process::std_out > boost::process::null, m_children);
//	}else {
//		boost::process::child(task.program.c_str(), boost::process::std_out > boost::process::null, m_children);
//	}

	return true;
}

